/*
 * serialize.cpp
 *
 *  Created on: 2012-9-26
 *      Author: Administrator
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>

#include "csSerialize.hpp"

static size_t makeCsMemberMember( char* write_to , const char* type , const char* name , const char* comment ) {
	if( comment == NULL ) {
		return sprintf( write_to , "		public %s %s ;\n"
				, type , name ) ;
	} else {
		return sprintf( write_to , "		public %s %s ;\t\t//%s\n"
				, type , name , comment ) ;
	}
}
static size_t makeCsListMember( char* write_to , const char* type , const char* name , const char* comment ) {
	if( comment == NULL ) {
		return sprintf( write_to , "		public uint32_t %sLength ;\n"
				"		public %s *%s ;\n"
				, name , type , name ) ;
	} else {
		return sprintf( write_to , "		public uint32_t %sLength ;\n"
				"		public %s *%s ;\n\t\t//%s"
				, name , type , name , comment ) ;
	}
}

/**
 * 构造函数
 */
size_t makeCsMember( char* write_to , xmlNode* node )  {
	char *pWrite = write_to ;
	xmlNode *memberNode ;
	memberNode = xmlFirstElementChild( node ) ;
	while( memberNode ) {
		const char* type = xmlGetProp( memberNode , "type" ) ;
		const char* name = xmlGetProp( memberNode , "name" ) ;
		const char* comment = xmlGetProp( memberNode , "comment" ) ;
		if( strcmp( type , "uint32_t" ) == 0
				|| strcmp( type , "int32_t" ) == 0 ) {
			type = "int" ;
		}
		if( xmlStrcmp( memberNode->name , "member" ) == 0 ) {
			pWrite += makeCsMemberMember( pWrite , type , name , comment ) ;
		}
		else if( xmlStrcmp( memberNode->name , "list" ) == 0 ) {
			pWrite += makeCsListMember( pWrite , type , name , comment ) ;
		}
		else {
			printf( "错误的成员类型：[%s]\n" , memberNode->name ) ;
			return 1 ;
		}
		memberNode = xmlNextElementSibling( memberNode ) ;
	}
	pWrite += sprintf( pWrite , "\n" ) ;
	return pWrite - write_to ;
}

/*
 * 序列化一个字段
 */
static size_t makeTypeSerialize( char* write_to , char* name ,char* type ) {
	char *pWrite = write_to ;
	if(	strcmp( type , "uint32_t" ) == 0
			|| strcmp( type , "int32_t" ) == 0
			|| strcmp( type , "float" ) == 0
			|| strcmp( type , "string" ) == 0 ) {
		pWrite += sprintf( pWrite , "\t\t\tnp.write( this.%s ) ;\n" , name ) ;
	} else {	// 自定义的数据类型
		pWrite += sprintf( pWrite , "\t\t\tthis.%s.serialize( np ) ;\n" , name ) ;
	}
	return pWrite - write_to ;
}

/**
 * 序列化
 */
size_t makeCsSerialize( char* write_to , xmlNode* node , enum SERIALIZE_TYPE serializeType ) {
	char *pWrite = write_to ;
	xmlNode* memberNode ;
	char nameList[256] ;

	pWrite += sprintf( pWrite , "\t\tpublic void serialize( Package np )\n"
			"\t\t{\n" ) ;
	if( serializeType == SERIALIZE_TYPE_RESPOND ) {
		// 应答的包加入模块号和消息号
		pWrite += sprintf( pWrite ,
				"\t\t\t np.write( ClietnProtocolDef.%s ) ;\n" , xmlGetProp( node , "notify" ) ) ;
	}
	memberNode = xmlFirstElementChild( node ) ;
	while( memberNode ) {
		char* type = xmlGetProp( memberNode , "type" ) ;
		char* name = xmlGetProp( memberNode , "name" ) ;
		if( xmlStrcmp( memberNode->name , "member" ) == 0 ) {
			pWrite += makeTypeSerialize( pWrite , name , type ) ;
		}
		else if( xmlStrcmp( memberNode->name , "list" ) == 0 ) {
			pWrite += sprintf( pWrite , "\t\t\tnp.write( this.%sLength ) ;\n" , name ) ;
			pWrite += sprintf( pWrite , "\t\t\tfor( int i = 0 ; i < %sLength ; ++i ) \n"
					"\t\t\t{\n" , name ) ;
			sprintf( nameList , "%s[i]" , name ) ;
			pWrite += makeTypeSerialize( pWrite , nameList , type ) ;
			pWrite += sprintf( pWrite , "\t\t\t}\n" ) ;
		}
		else {
			printf( "错误的成员类型：[%s]\n" , memberNode->name ) ;
			return 1 ;
		}
		memberNode = xmlNextElementSibling( memberNode ) ;
	}
	pWrite += sprintf( pWrite , "\t\t} \n\n" ) ;

	return pWrite - write_to ;
}

/*
 * 反序列化一个字段
 */
static size_t makeTypeUnserialize( char* write_to , char* name ,char* type ) {
	char *pWrite = write_to ;
	if(	strcmp( type , "uint32_t" ) == 0
			|| strcmp( type , "int32_t" ) == 0
			|| strcmp( type , "float" ) == 0
			|| strcmp( type , "string" ) == 0 ) {
		pWrite += sprintf( pWrite , "\t\t\tnp.read( out this.%s ) ;\n" , name ) ;
	} else {	// 自定义的数据类型
		pWrite += sprintf( pWrite , "\t\t\tthis.%s.unSerialize( np ) ;\n" , name ) ;
	}
	return pWrite - write_to ;
}

/*
 * 反序列化
 */
size_t makeCsUnserialize( char* write_to , xmlNode *node ) {
	char *pWrite = write_to ;
	xmlNode* memberNode ;
	char nameList[256] ;

	pWrite += sprintf( pWrite , "\t\tpublic void unSerialize( Package np )\n"
			"\t\t{\n" ) ;
	memberNode = xmlFirstElementChild( node ) ;
	while( memberNode ) {
		char* type = xmlGetProp( memberNode , "type" ) ;
		char* name = xmlGetProp( memberNode , "name" ) ;
		if( xmlStrcmp( memberNode->name , "member" ) == 0 ) {
			pWrite += makeTypeUnserialize( pWrite , name , type ) ;
		}
		else if( xmlStrcmp( memberNode->name , "list" ) == 0 ) {
			pWrite += sprintf( pWrite , "\t\t\tnp.read(this.%sLength) ;\n" , name ) ;
			pWrite += sprintf( pWrite , "\t\t\tfor( int i = 0 ; i < this.%sLength ; ++i ) {\n" , name ) ;
			sprintf( nameList , "%s[i]" , name ) ;
			pWrite += makeTypeUnserialize( pWrite , nameList , type ) ;
			pWrite += sprintf( pWrite , "\t\t\t}\n" ) ;
		}
		else {
			printf( "错误的成员类型：[%s]\n" , memberNode->name ) ;
			return 1 ;
		}
		memberNode = xmlNextElementSibling( memberNode ) ;
	}
	pWrite += sprintf( pWrite , "\t\t} \n\n" ) ;

	return pWrite - write_to ;
}






























